home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / mega src / Source / rm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-17  |  6.6 KB  |  300 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     rm.c
  4.     
  5.     Copyright (c) 1993,1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. //
  16. // This code can build to be "rm" or "rmdir".
  17. //
  18. // To build "rm", define RM below.
  19. //
  20. // To build "rmdir", define RMDIR below.
  21. //
  22.  
  23. #define  RM
  24.  
  25. #include <script.h>
  26. #include <string.h>
  27.  
  28. #include "nshc.h"
  29.  
  30. #include "arg_utl.proto.h"
  31. #include "fss_utl.proto.h"
  32. #include "fss_utl2.proto.h"
  33. #include "nshc_utl.proto.h"
  34. #include "str_utl.proto.h"
  35.  
  36. // data definition - this struct is the root of all data
  37.  
  38. typedef struct {
  39.  
  40.     int        got_fss;        // 0 if FSSpec calls are not available
  41.     int        arg;            // position in arg list
  42.  
  43. } t_rm_data;
  44.  
  45. typedef    t_rm_data    **rm_hndl;
  46.  
  47. /* ======================================== */
  48.  
  49. // prototypes - utility
  50.  
  51. void rm_bad( t_nshc_parms *nshc_parms, int code );
  52. void rm_bad_file( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg );
  53. void rm_good( t_nshc_parms *nshc_parms );
  54.  
  55. // prototypes - file routines
  56.  
  57. OSErr rm_info(const FSSpec *spec, long *theDirID, int *isDir, int *isEmpty);
  58. void  rm_one( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_rm_data **hData );
  59.  
  60. // prototypes - state machine
  61.  
  62. void rm_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  );
  63. void rm_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  64. void rm_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  65.  
  66. /* ======================================== */
  67.  
  68. // utility routines
  69.  
  70. /* ======================================== */
  71.  
  72. void rm_bad(  t_nshc_parms *nshc_parms, int code )
  73. {
  74.     nshc_parms->action = nsh_stop;
  75.     nshc_parms->result = code;
  76. }
  77.  
  78. void rm_bad_file(  t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, StringPtr msg )
  79. {
  80.  
  81. #if defined RM
  82.     nshc_calls->NSH_putStr_err("\prm: File access error (");
  83. #elif defined RMDIR
  84.     nshc_calls->NSH_putStr_err("\prmdir: Directory access error (");
  85. #endif
  86.  
  87.     nshc_calls->NSH_putStr_err(msg);
  88.     nshc_calls->NSH_putStr_err("\p)\r");
  89.  
  90.     nshc_parms->action = nsh_stop;
  91.     nshc_parms->result = NSHC_ERR_GENERAL;
  92. }
  93.  
  94. void rm_good(  t_nshc_parms *nshc_parms )
  95. {
  96.     nshc_parms->action = nsh_stop;
  97.     nshc_parms->result = 0;
  98. }
  99.  
  100. /* ======================================== */
  101.  
  102. // file access routines
  103.  
  104. /* ========================================== */
  105.  
  106. OSErr rm_info(const FSSpec *spec, long *theDirID, int *isDir, int *isEmpty)
  107. {
  108.     CInfoPBRec pb;
  109.     OSErr error;
  110.  
  111.     pb.hFileInfo.ioNamePtr = (StringPtr)spec->name;
  112.     pb.hFileInfo.ioVRefNum = spec->vRefNum;
  113.     pb.hFileInfo.ioDirID = spec->parID;
  114.     pb.hFileInfo.ioFDirIndex = 0;
  115.     
  116.     error = PBGetCatInfoSync(&pb);
  117.     
  118.     *theDirID = pb.hFileInfo.ioDirID;
  119.     *isDir = (pb.hFileInfo.ioFlAttrib & 0x10) != 0;
  120.     *isEmpty = pb.dirInfo.ioDrNmFls == 0;
  121.         
  122.     return (error);
  123. }
  124.  
  125. /* ======================================== */
  126.  
  127. void rm_one( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls, t_rm_data **hData )
  128. {
  129.     int        result;
  130.     FSSpec    fsspec;
  131.     long    dirID;
  132.     int        isDir;
  133.     int        isEmpty;
  134.     
  135.     // =====> convert argument to fsspec
  136.     
  137.     result = arg_to_real_fss( nshc_parms, nshc_calls, (**hData).arg, &fsspec );
  138.  
  139.     (**hData).arg++;
  140.     
  141.     if (result) {
  142.         rm_bad( nshc_parms, result );
  143.         return;
  144.         }
  145.     
  146.     result = rm_info( &fsspec, &dirID, &isDir, &isEmpty );
  147.     
  148. #if defined RM
  149.  
  150.     if ( !result && isDir ) {
  151.         nshc_calls->NSH_putStr_err("\prm: Skiping directory = ");
  152.         nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  153.         nshc_calls->NSH_putchar('\r');
  154.         return;
  155.         }
  156.  
  157. #elif defined RMDIR
  158.  
  159.     if (!result) {
  160.     
  161.         if ( !isDir ) {
  162.             nshc_calls->NSH_putStr_err("\prmdir: Skiping file = ");
  163.             nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  164.             nshc_calls->NSH_putchar('\r');
  165.             return;
  166.             }
  167.     
  168.         if ( !isEmpty ) {
  169.             nshc_calls->NSH_putStr_err("\prmdir: Directory is not empty = ");
  170.             nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  171.             nshc_calls->NSH_putchar('\r');
  172.             return;
  173.             }
  174.         
  175.         }
  176.  
  177. #endif
  178.             
  179.     if ( result == fnfErr ) {
  180.  
  181.         #if defined RM
  182.         nshc_calls->NSH_putStr_err("\prm: File not found = ");
  183.         #elif defined RMDIR
  184.         nshc_calls->NSH_putStr_err("\prmdir: Directory not found = ");
  185.         #endif
  186.  
  187.         nshc_calls->NSH_putStr_err((StringPtr)fsspec.name);
  188.         nshc_calls->NSH_putchar('\r');
  189.         return;
  190.         }
  191.             
  192.     if ( result ) {
  193.         rm_bad_file( nshc_parms, nshc_calls, (StringPtr)fsspec.name );
  194.         nshc_calls->NSH_printf( "error = %d\r", result );
  195.         return;
  196.         }
  197.             
  198.     // =====> delete the file or directory
  199.         
  200.     result = fss_Delete((**hData).got_fss, &fsspec);
  201.     
  202.     if ( result ) {
  203.         rm_bad_file( nshc_parms, nshc_calls, (StringPtr)fsspec.name );
  204.         return;
  205.         }
  206.  
  207.     result = fss_wake_parent( &fsspec );
  208.  
  209.     if (result)
  210.         nshc_calls->NSH_putStr_err( "\pmv: Warning - could update finder info.\r" );
  211. }
  212.  
  213. /* ======================================== */
  214.  
  215. // state machine - core routines
  216.  
  217. /* ======================================== */
  218.  
  219. void rm_start( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls  )
  220. {
  221.     rm_hndl    hData;    // handle to hold our data
  222.     
  223.     if (nshc_parms->argc < 2) {
  224.     
  225.         #if defined RM
  226.         nshc_calls->NSH_putStr_err( "\pUsage: rm file [file...]\r" );
  227.         #elif defined RMDIR
  228.         nshc_calls->NSH_putStr_err( "\pUsage: rmdir dir [dir...]\r" );
  229.         #endif
  230.  
  231.         rm_bad( nshc_parms, NSHC_ERR_PARMS );
  232.         return;
  233.         }
  234.         
  235.     nshc_parms->action = nsh_continue;
  236.  
  237.     hData = (rm_hndl)NewHandleClear(sizeof(t_rm_data));
  238.     
  239.     if (hData) {
  240.         (**hData).arg = 1;                    // start at the arg = 1 position
  241.         (**hData).got_fss = fss_test();        // test if we can use FSSpec calls
  242.         nshc_parms->data = (Handle)hData;
  243.         }
  244.     else {
  245.         nshc_calls->NSH_putStr_err( "\prm: Could not allocate storage.\r" );
  246.         rm_bad( nshc_parms, NSHC_ERR_MEMORY );
  247.         }
  248. }
  249.  
  250. /* ======================================== */
  251.  
  252. void rm_continue( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  253. {
  254.     int        i;
  255.     rm_hndl    hData;
  256.     
  257.     if (hData = (rm_hndl)nshc_parms->data) {
  258.  
  259.         if ((**hData).arg >= nshc_parms->argc)
  260.             rm_good( nshc_parms );
  261.         else
  262.             rm_one( nshc_parms, nshc_calls, hData );
  263.  
  264.         }
  265. }
  266.  
  267. /* ======================================== */
  268.  
  269. void rm_stop( t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  270. {
  271.     rm_hndl    hData;
  272.     
  273.     if (hData = (rm_hndl)nshc_parms->data)
  274.         DisposeHandle(nshc_parms->data);
  275.         
  276.     nshc_parms->action = nsh_idle;
  277. }
  278.  
  279. /* ======================================== */
  280.  
  281. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  282. {
  283.     
  284.     if (nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION )) return;
  285.     
  286.     switch (nshc_parms->action) {
  287.         case nsh_start:
  288.             rm_start(nshc_parms, nshc_calls);
  289.             break;
  290.         case nsh_continue:
  291.             rm_continue(nshc_parms, nshc_calls);
  292.             break;
  293.         case nsh_stop:
  294.             rm_stop(nshc_parms, nshc_calls);
  295.             break;
  296.         }
  297. }
  298.  
  299. /* ======================================== */
  300.